#include "CStorage.h"
#include "../item/CItemMgr.h"
#include "../mainctrl.h"

void CStorageItemGroupKey::Init(unsigned char ucItemType, unsigned int uiItemId)
{
    _ucItemType  =  ucItemType;
    switch (ucItemType)
    {
        case ITEM_TYPE_EQUIP:
        {
            if (uiItemId >= EQUIP_CONFIG_ID_MOD)
            {
                unsigned short usConfigId;
                CMainCtrl::m_pstMain->m_stEquipMgr.GetConfigIdByEquipId(uiItemId, usConfigId);
                _uiItemCfgID = usConfigId;
            }
            else
            {
                _uiItemCfgID = uiItemId;
            }

            break;
        }
        default:
        {
            _uiItemCfgID = uiItemId;
        }
    }
	return ;
}

bool CStorageGrid::IsValidGrid ()
{
    if (_shCount <= 0)
    {
        return false;
    }

    CItemConfigData stConfigData;
    int iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetConfig(_stKey._ucItemType, _stKey._uiItemID, stConfigData);
    if (iRet || stConfigData._iUseGrid <=0 || stConfigData._shMaxCountPerGrid <= 0)
    {
        return false;
    }

    return true;
}

int CStorageGrid::Init (unsigned int uiItemType, unsigned int uiItemID)
{
    int iRet;
    CItemConfigData stConfigData;
    iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetConfig(uiItemType, uiItemID, stConfigData);
    CHECK_RETURN(iRet);

    Clear();
    _shMaxPerGrid = stConfigData._shMaxCountPerGrid;
    _iPosValue    = stConfigData._iPosValue;
    _shCount = 0;
    _stKey._uiItemID = uiItemID;
    _stKey._ucItemType = uiItemType;
    return 0;
}

void CStorageHash::Clear()
{
    for (int iIndex = this->GetHeadIndex();
        iIndex >= 0; iIndex = this->GetHeadIndex())
    {
        this->HashFreeByIndex(iIndex);
    }

    for (int iIndex = _stItemTypeHash.GetHeadIndex();
        iIndex >= 0; iIndex = _stItemTypeHash.GetHeadIndex())
    {
        _stItemTypeHash.HashFreeByIndex(iIndex);
    }
}

size_t CStorageHash::CountSize(int iObjectCount)
{
    const size_t iSize = CTLib::CTObjectMgr<T_STORAGE_HASH::TPair>::CountSize(iObjectCount, sizeof(T_STORAGE_HASH::TPair), 2, 3)
        + T_STORAGE_ITEM_TYPE_HASH::CountSize(iObjectCount);
    return iSize;
}

int CStorageHash::Init(const char* pBuffer, int iObjectCount, bool bResetShm)
{
    int iRet = 0;
    size_t BuffOffset = 0;

    iRet = T_STORAGE_HASH::Init(pBuffer + BuffOffset, iObjectCount, 2, 3, bResetShm);
    CHECK_RETURN(iRet);
    BuffOffset += CTLib::CTObjectMgr<T_STORAGE_HASH::TPair>::CountSize(iObjectCount, sizeof(T_STORAGE_HASH::TPair), 2, 3);

    m_stMgr.BuildEachList(ITEM_TYPE_INDEX);
    for (int i = 0; i < iObjectCount; ++i)
    {
        m_stMgr.Flag(i, ITEM_TYPE_INDEX) = -1;
    }

    iRet = _stItemTypeHash.Init(pBuffer + BuffOffset, iObjectCount);
    if (iRet != 0)
    {
        return iRet;
    }

    return 0;
}

int CStorageHash::HashAlloc(const CStorageKey& stKey, bool bFindExist)
{
    int iRet = 0;

    int iIndex = T_STORAGE_HASH::HashAlloc(stKey, bFindExist);
    if (iIndex < 0)
    {
        return iIndex;
    }

    CStorageItemGroupKey stItemGroupKey;
    stItemGroupKey.Init(stKey._ucItemType, stKey._uiItemID);

    int iItemIndex = _stItemTypeHash.HashFind(stItemGroupKey);
    if (iItemIndex < 0) //没有此类物品的数据
    {
        iItemIndex = _stItemTypeHash.HashAlloc(stItemGroupKey);
        if (iItemIndex < 0)
        {
            return iItemIndex;
        }

        _stItemTypeHash[iItemIndex] = iItemIndex;
        m_stMgr.Flag(_stItemTypeHash[iItemIndex], ITEM_TYPE_INDEX) = iIndex;
    }
    else
    {
        iRet = m_stMgr.EachListAppend(iIndex, ITEM_TYPE_INDEX,
            m_stMgr.Flag(_stItemTypeHash[iItemIndex], ITEM_TYPE_INDEX));
        if (iRet) // 调整失败
        {
            return -1;
        }
    }

    return iIndex;
}

int CStorageHash::HashFind(const CStorageKey& stKey)
{
    return T_STORAGE_HASH::HashFind(stKey);
}

int CStorageHash::HashFind(const CStorageItemGroupKey& stKey)
{
    int iItemIndex = _stItemTypeHash.HashFind(stKey);
    if (iItemIndex < 0)
    {
        return iItemIndex;
    }

    return m_stMgr.Flag(_stItemTypeHash[iItemIndex], ITEM_TYPE_INDEX);
}

int CStorageHash::FindNextSameTypeItem(int iIndex)
{
    if (iIndex < 0 || iIndex >= m_stMgr.GetObjectCount())
    {
        return -1;
    }

    return m_stMgr.Next(iIndex, ITEM_TYPE_INDEX);
}

int CStorageHash::HashFreeByIndex(int i)
{
    if (i < 0 || i >= m_stMgr.GetObjectCount())
    {
        return -1;
    }

    CStorageItemGroupKey stItemGroupKey;
    stItemGroupKey.Init(m_stMgr[i].stKey._ucItemType, m_stMgr[i].stKey._uiItemID);
    int iItemIndex = _stItemTypeHash.HashFind(stItemGroupKey);
    if (iItemIndex < 0)
    {
        CT_ERROR(("free storage item but no this type, %u %d",
            stItemGroupKey._uiItemCfgID, stItemGroupKey._ucItemType));
        return iItemIndex;
    }

    if (m_stMgr.Prev(i, ITEM_TYPE_INDEX) == -1) // 头部
    {
        m_stMgr.Flag(_stItemTypeHash[iItemIndex], ITEM_TYPE_INDEX) = m_stMgr.Next(i, ITEM_TYPE_INDEX);
    }

    if (m_stMgr.Flag(_stItemTypeHash[iItemIndex], ITEM_TYPE_INDEX) == -1)   //没有这类了
    {
        _stItemTypeHash.HashFreeByIndex(iItemIndex);
    }

    m_stMgr.EachListRemove(i, ITEM_TYPE_INDEX);

    return T_STORAGE_HASH::HashFreeByIndex(i);
}

